package com.party.web.web.controller.article;

import com.alibaba.fastjson.JSONObject;
import com.party.common.paging.Page;
import com.party.common.utils.LangUtils;
import com.party.common.utils.StringUtils;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.article.Article;
import com.party.core.model.channel.Channel;
import com.party.core.model.commune.MomentType;
import com.party.core.model.subject.Subject;
import com.party.core.model.subject.SubjectApply;
import com.party.core.model.system.Dict;
import com.party.core.model.system.DictEnum;
import com.party.core.model.user.User;
import com.party.core.service.article.IArticleService;
import com.party.core.service.channel.IChannelService;
import com.party.core.service.cos.CosBizService;
import com.party.core.service.subject.ISubjectApplyService;
import com.party.core.service.subject.ISubjectService;
import com.party.core.service.system.IDictService;
import com.party.core.service.user.IUserService;
import com.party.web.biz.article.ArticleBizService;
import com.party.web.biz.file.FileBizService;
import com.party.web.biz.member.CMomentBizService;
import com.party.web.biz.system.member.MemberGroupBizService;
import com.party.core.utils.MyBeanUtils;
import com.party.web.utils.RealmUtils;
import com.party.web.web.dto.AjaxResult;
import com.party.web.web.dto.input.common.CommonInput;
import com.party.web.web.dto.output.article.ArticleOutput;
import com.party.web.web.dto.output.member.CMomentSave;
import org.apache.commons.lang3.StringEscapeUtils;
import org.aspectj.weaver.loadtime.Aj;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.*;

/**
 * 文章
 *
 * @author Administrator
 */
@Controller
@RequestMapping(value = "/article/article")
public class ArticleController {

    @Autowired
    private IArticleService articleService;

    @Autowired
    private IDictService dictService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IChannelService channelService;

    @Autowired
    private FileBizService fileBizService;

    @Autowired
    private ISubjectApplyService subjectApplyService;

    @Autowired
    private ISubjectService subjectService;

    @Autowired
    private CosBizService cosBizService;

    @Autowired
    private ArticleBizService articleBizService;

    @Autowired
    private CMomentBizService momentBizService;

    @Autowired
    private MemberGroupBizService memberGroupBizService;

    protected static Logger logger = LoggerFactory.getLogger(ArticleController.class);

    /**
     * 跳转至列表 我发布的文章
     * subject/subject/subjectList.do
     *
     * @return
     */
    @RequestMapping(value = "articleList")
    public ModelAndView articleList(Article article, Page page, CommonInput commonInput) {
        ModelAndView mv = new ModelAndView("article/articleList");
        article.setDelFlag(BaseModel.DEL_FLAG_NORMAL);

        String memberId = RealmUtils.getCurrentUser().getId();
        article.setMemberId(memberId);
        Map<String, Object> params = CommonInput.appendParams(commonInput);
        List<Article> articles = articleService.webListPage(article, params, page);

        String path = fileBizService.getUploadCIPath(memberId, "article");
        List<ArticleOutput> articleOutputs = LangUtils.transform(articles, input -> {
            ArticleOutput articleOutput = ArticleOutput.transform(input);
            String articleType = input.getArticleType();
            Dict dict = new Dict();
            dict.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
            dict.setType(DictEnum.ARTICLE_TYPE.getCode());
            dict.setValue(articleType);
            Dict dictEntity = dictService.getByProperty(dict);
            if (dictEntity != null) {
                articleOutput.setArticleType(dictEntity.getLabel());
            }

            if (input.getChannel() != null) {
                Channel channel = channelService.get(input.getChannel().getId());
                articleOutput.setChannel(channel);
            }

            String fileName = "detail_" + input.getId();
            String qrCodeUrl = cosBizService.getPreviewPictureUrl(path + fileName);
            articleOutput.setQrCodeUrl(qrCodeUrl);

            return articleOutput;
        });

        Dict dict = new Dict();
        dict.setType(DictEnum.ARTICLE_TYPE.getCode());
        mv.addObject("articleTypes", dictService.list(dict));

        mv.addObject("articles", articleOutputs);
        mv.addObject("page", page);
        mv.addObject("input", commonInput);
        return mv;
    }

    /**
     * 跳转至发布
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "publishArticle")
    public ModelAndView publishArticle(String id, String applyId, String channelId, String subjectId) {
        ModelAndView mv = new ModelAndView("article/publishArticle");
        if (StringUtils.isNotEmpty(id)) {
            Article article = articleService.get(id);
            String content = StringUtils.unescapeHtml4Video2Iframe(article.getContent());
            article.setContent(content);
            mv.addObject("article", article);
        }

        Dict dict = new Dict();
        dict.setType(DictEnum.ARTICLE_TYPE.getCode());
        dict.setOpenStatus(YesNoStatus.YES.getCode());
        mv.addObject("types", dictService.list(dict));
        if (StringUtils.isNotEmpty(applyId)) {
            SubjectApply subjectApply = subjectApplyService.get(applyId);
            mv.addObject("subjectApply", subjectApply);
            Subject subject = subjectService.get(subjectApply.getSubjectId());
            mv.addObject("subject", subject);
            mv.addObject("applyType", subjectApply.getType());
        }
        if (StringUtils.isEmpty(channelId)) {
            Channel channel = new Channel();
            channel.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
            channel.setMember(applyId);
            List<Channel> channels = channelService.list(channel);
            mv.addObject("channels", channels);
        } else {
            Channel channel = channelService.get(channelId);
            mv.addObject("channel", channel);
        }

        mv.addObject("subjectId", subjectId);
        return mv;
    }

    /**
     * 跳转至详情
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "articleDetail")
    public ModelAndView articleDetail(String id, String applyId) {
        ModelAndView mv = new ModelAndView("article/articleDetail");
        Article article = articleService.get(id);
        if (StringUtils.isNotEmpty(article.getContent())) {
            article.setContent(StringUtils.unescapeHtml4Video2Iframe(article.getContent()));
        }
        String articleType = article.getArticleType();
        Dict dict = new Dict();
        dict.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        dict.setType(DictEnum.ARTICLE_TYPE.getCode());
        dict.setValue(articleType);
        Dict dictEntity = dictService.getByProperty(dict);
        if (dictEntity != null) {
            article.setArticleType(dictEntity.getLabel());
        }

        if (article.getChannel() != null) {
            Channel channel = channelService.get(article.getChannel().getId());
            article.setChannel(channel);
        }

        mv.addObject("article", article);

        if (StringUtils.isNotEmpty(applyId)) {
            SubjectApply subjectApply = subjectApplyService.get(applyId);
            mv.addObject("subjectApply", subjectApply);
            Subject subject = subjectService.get(subjectApply.getSubjectId());
            mv.addObject("subject", subject);
        }

        return mv;
    }


    /**
     * 发布保存
     *
     * @param article
     * @param result
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "save")
    public AjaxResult save(Article article, BindingResult result, String channelId, String applyId, String subjectId) throws Exception {
        AjaxResult ajaxResult = new AjaxResult();
        String memberId = RealmUtils.getCurrentUser().getId();
        if (RealmUtils.getNewCurrentUser().isXzgsAdmin()) {
            memberId = RealmUtils.getNewCurrentUser().getPartnerId();
        }
        // 数据验证
        if (result.hasErrors()) {
            List<ObjectError> allErros = result.getAllErrors();
            ajaxResult.setDescription(allErros.get(0).getDefaultMessage());
            return ajaxResult;
        }

        if (StringUtils.isNotEmpty(article.getContent())) {
            String content = StringUtils.escapeHtml4Iframe2Video(article.getContent().trim());
            article.setContent(content);
        }
        SubjectApply apply = null;
        if (StringUtils.isNotEmpty(applyId)) {
            apply = subjectApplyService.get(applyId);
            if (apply.getType().equals("channel")) {
                article.setArticleGroupId(apply.getTargetId());
            }
        }

        if (StringUtils.isNotEmpty(article.getId())) {
            Article t = articleService.get(article.getId());
            MyBeanUtils.copyBeanNotNull2Bean(article, t);// 将编辑表单中的非NULL值覆盖数据库记录中的值
            articleService.update(t);

            memberId = t.getCreateBy();
        } else {
            if (article.getReadNum() == null) {
                article.setReadNum(0);
            }
            User user = userService.findByLoginName("admin");
            article.setCreateBy(user.getId());
            article.setUpdateBy(user.getId());
            article.setMemberId(memberId);
            if (StringUtils.isNotEmpty(channelId)) {
                Channel channel = channelService.get(channelId);
                article.setChannel(channel);
            }

            String articleId = articleService.insert(article);
            if (apply != null && apply.getType().equals("article")) {
                apply.setUrl(SubjectApply.MIC_URL + "article/article_detail.html?id=" + articleId);
                apply.setTargetId(articleId);
                apply.setUpdateDate(new Date());
                subjectApplyService.update(apply);
            }

            try {
                CMomentSave cMomentSave = new CMomentSave();
                cMomentSave.setPartnerId(article.getMemberId());
                cMomentSave.setBizId(article.getId());
                cMomentSave.setArticle(article);
                cMomentSave.setMomentType(MomentType.NEWS.getCode());
                momentBizService.businessSaveCMoment(cMomentSave);
            } catch (Exception e) {
                logger.error("发布文章同时发布动态--失败");
            }
        }
        if (apply != null) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("applyId", apply.getId());
            map.put("subjectId", apply.getSubjectId());
            ajaxResult.setData(map);
        }

        try {
            articleBizService.uploadQrCode(memberId, article.getId());
        } catch (Exception e) {
            logger.error("生成文章二维码异常", e);
        }

        ajaxResult.setSuccess(true);
        return ajaxResult;
    }

    /**
     * 删除文章
     */
    @ResponseBody
    @RequestMapping(value = "delete")
    public AjaxResult delete(String articleId, String subjectId, String applyId) {
        AjaxResult ajaxResult = new AjaxResult();
        try {
            if (StringUtils.isEmpty(articleId)) {
                return new AjaxResult(false);
            }
            if (StringUtils.isNotEmpty(subjectId)) {
                ajaxResult.setData(subjectId);
            }
            articleService.delete(articleId);
            if (StringUtils.isNotEmpty(applyId)) {
                SubjectApply subjectApply = subjectApplyService.get(applyId);
                if (subjectApply.getType().equals("article")) {
                    subjectApply.setTargetId("");
                    subjectApplyService.update(subjectApply);
                }
            }
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("applyId", applyId);
            map.put("subjectId", subjectId);
            ajaxResult.setData(map);
            ajaxResult.setSuccess(true);
            return ajaxResult;
        } catch (Exception e) {
            logger.error("文章删除异常", e);
        }
        ajaxResult.setSuccess(false);
        return ajaxResult;
    }

    /**
     * 读取频道下的文章
     *
     * @param page
     * @param channelId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "getArticleByChanne")
    public Map<String, Object> publishListJson(Page page, String channelId) {
        Article article = new Article();
        Channel channel = new Channel();
        channel.setId(channelId);
        article.setChannel(channel);
        article.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        List<Article> articles = articleService.listPage(article, page);

        for (Article entity : articles) {
            String articleType = entity.getArticleType();
            Dict dict = new Dict();
            dict.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
            dict.setType(DictEnum.ARTICLE_TYPE.getCode());
            dict.setValue(articleType);
            Dict dictEntity = dictService.getByProperty(dict);
            if (dictEntity != null) {
                entity.setArticleType(dictEntity.getLabel());
            }
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("articles", articles);
        map.put("page", page);
        return map;
    }

    /**
     * 拖曳更新排序
     *
     * @param jsonStr 排序json字符串
     * @return
     */
    @ResponseBody
    @RequestMapping("dragUpdateSort")
    public AjaxResult dragUpdateSort(String jsonStr) {
        if (StringUtils.isEmpty(jsonStr)) {
            return AjaxResult.error("文章排序json字符串不能为空");
        }
        Map<String, Integer> resultMap = JSONObject.parseObject(jsonStr, Map.class);
        for (Map.Entry<String, Integer> result : resultMap.entrySet()) {
            String articleId = result.getKey(); // 文章id
            Integer newSort = result.getValue(); // 排序号
            Article article = articleService.get(articleId);
            article.setSort(newSort);
            articleService.update(article);
        }
        return AjaxResult.success();
    }

    @ResponseBody
    @RequestMapping("upDownUpdateSort")
    public AjaxResult upDownUpdateSort(String articleId, String type, String applyId) {
        if (StringUtils.isEmpty(type)) {
            return AjaxResult.error("操作类型不能为空");
        }
        if (StringUtils.isEmpty(articleId)) {
            return AjaxResult.error("文章id不能为空");
        }
        try {
            SubjectApply subjectApply = subjectApplyService.get(applyId);
            Article t = new Article();
            t.setArticleGroupId(subjectApply.getTargetId());
            List<Article> articles = articleService.list(t);
            Collections.sort(articles, new Comparator<Article>() {
                @Override
                public int compare(Article o1, Article o2) {
                    if (null == o1.getSort()) return 1;
                    if (null == o2.getSort()) return 1;
                    return o1.getSort() >= o2.getSort() ? 1 : -1;
                }
            });

            for (int i = 0; i < articles.size(); i++) {
                Article entity = articles.get(i);
                if (null == entity.getSort()) {
                    entity.setSort(articles.size());
                    articleService.update(entity);
                }
                if (entity.getId().equals(articleId)) {
                    if ("up".equals(type)) {
                        if (i - 1 > 0) {
                            Article before = articles.get(i - 1);
                            before.setSort(before.getSort() + 1);
                            articleService.update(before);
                        }
                        break;
                    } else if ("down".equals(type)) {
                        if (i + 1 < articles.size()) {
                            Article after = articles.get(i + 1);
                            after.setSort(after.getSort() - 1);
                            articleService.update(after);
                        }
                        break;
                    }
                }
            }

            Article article = articleService.get(articleId);
            if ("up".equals(type)) {
                if (article.getSort() == 1) {
                    return AjaxResult.error("已经是第一位了");
                }
                article.setSort(article.getSort() - 1);
            } else if ("down".equals(type)) {
                article.setSort(article.getSort() + 1);
            }
            articleService.update(article);
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("更新排序异常", e);
            return AjaxResult.error("更新排序异常");
        }
    }

    /**
     * 根据类型获取列表
     *
     * @param page        分页参数
     * @param articleType 类型
     * @return
     */
    @RequestMapping("indexArticleFindByType")
    public ModelAndView indexArticleFindByType(Page page, String articleType) {
        page.setLimit(10);
        Article article = new Article();
        article.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        article.setArticleType(articleType);
        Dict dict = new Dict();
        dict.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        dict.setType(DictEnum.ARTICLE_TYPE.getCode());
        dict.setValue(articleType);
        Dict dictEntity = dictService.getByProperty(dict);
        List<Article> articleList = articleService.listPage(article, page);
        for (Article db : articleList) {
            db.setContent(null);
        }
        ModelAndView modelAndView = new ModelAndView("crm/articleList");
        modelAndView.addObject("articleList", articleList);
        modelAndView.addObject("type", dictEntity);
        modelAndView.addObject("page", page);
        return modelAndView;
    }

    /**
     * 跳转至详情
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "indexArticleDetail")
    public ModelAndView indexArticleDetail(String id) {
        Article article = articleService.get(id);
        if (StringUtils.isNotEmpty(article.getContent())) {
            article.setContent(StringUtils.unescapeHtml4Video2Iframe(article.getContent()));
        }
        String articleType = article.getArticleType();
        Dict dict = new Dict();
        dict.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        dict.setType(DictEnum.ARTICLE_TYPE.getCode());
        dict.setValue(articleType);
        Dict dictEntity = dictService.getByProperty(dict);
        if (dictEntity != null) {
            article.setArticleType(dictEntity.getLabel());
        }

        ModelAndView modelAndView = new ModelAndView("crm/articleDetail");
        modelAndView.addObject("article", article);
        return modelAndView;
    }

}
